package hn.cch.framework.google.guice;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.name.Names;
import hn.cch.framework.google.guice.service.AbstractService;
import hn.cch.framework.google.guice.service.CustomService;
import hn.cch.framework.google.guice.service.ExtendService;
import hn.cch.framework.google.guice.module.ParentModule;
import hn.cch.framework.google.guice.module.CustomModule;
import hn.cch.framework.google.guice.service.FieldValue;
import hn.cch.framework.google.guice.service.NamedClass;
import hn.cch.framework.google.guice.service.ServiceInterface;
import hn.cch.framework.google.guice.service.ServiceProvider;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class GuiceTest {

    private final static Logger logger = LoggerFactory.getLogger(GuiceTest.class);


    @Test
    public void testGuice() {
        Injector injector = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                // 单例模式
                bind(AbstractService.class).to(CustomService.class);
                // bind(AbstractService.class).to(CustomService.class).in(Singleton.class);
                // bind(AbstractService.class).toInstance(new CustomService());

                // bind(Key.get(AbstractService.class)).toProvider(ServiceProvider.class);

                // 泛型
                bind(new TypeLiteral<List<AbstractService>>() {
                }).toInstance(
                    new ArrayList<>(Arrays.asList(new CustomService(), new ExtendService())));


                // 集合
                Multibinder<AbstractService> multibinder = Multibinder.newSetBinder(binder(), AbstractService.class);
                multibinder.addBinding().toInstance(new CustomService());
                multibinder.addBinding().toInstance(new ExtendService());
            }
        });

        injector.injectMembers(this);

        ServiceInterface serviceInterface = injector.getInstance(ServiceInterface.class);
        AbstractService abstractService = injector.getInstance(AbstractService.class);


        logger.info("result:{}", serviceInterface.handle("JAVA"));
        logger.info("result:{}", abstractService.handle("JAVA"));

    }

    @Test
    public void testInjector() {

        Injector injector = Guice.createInjector(new ParentModule());
        Injector childInjector = injector.createChildInjector(new CustomModule());

    }

    @Test
    public void TestNamed() {
        Injector injector = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                bind(String.class).annotatedWith(Names.named("string")).toInstance("string");
                bindConstant().annotatedWith(FieldValue.class).to("field");
            }
        });

        NamedClass namedClass = injector.getInstance(NamedClass.class);
        logger.info("NamedClass:{}", namedClass.toString());

    }

}



